package com.ys.io.p2缓冲字符流;


import java.io.*;


/**
 * 描述:
 * 流的分年内
 *
 * @author CodeYang
 * @version 2020/12/30 20:09
 */
public class 缓存字符输入输出流 {

    public static void main(String[] args) {

        //method01();
        // method02();
        // method03();
        method04();

    }

    /**
     * 描述:
     * 字符缓冲流读,末尾为null
     * 处理换行
     *
     * <code>使用缓冲流可以减少程序与磁盘交互的次数</code>
     *    读写都是从缓冲区里去读和填数据,缓冲区不满不会与磁盘交互读写下一次
     * 场景：使用字符缓冲流进行文本文件的拷贝粘贴
     * * 步骤：
     * * 1 定义try catch resources
     * * 2 创建FileReader和FileWriter对象并指定源路径和目的路径
     * * 3 创建BufferedReader对象和BufferedWriter对象
     * * 4 将FileReader和FileWriter注入到BufferedReader和BufferedWriter里面
     * * 5 定义一个String类型的变量存储每次读取的一行数据
     * * 6 调用BufferedReader的readLine()方法从缓冲区读取一行数据
     * * 7 判断读取的结果是否为空，如果为空表示读取到末尾，停止读取。
     * *   如果非空，将读取的数据使用BufferedWriter的write(str)方法写入目的路径
     * * 8 调用BufferedWriter的newLine()方法进行换行
     */
    private static void method04() {

        // 缓冲流不能字节存在,必须使用父类的传递注入使用 缓冲流只是一个桥梁 其默认大小为8192/1024 8KB
         try(
                 // 字符流读文件 添加进入字符缓冲流
                 FileReader fileReader = new FileReader("day_23/源码.txt");
                 BufferedReader bf = new BufferedReader(fileReader);
                 // 写 使用字符缓冲流来写文件
                 FileWriter fw = new FileWriter("day_23/源码拷贝.txt");
                 BufferedWriter bfw = new BufferedWriter(fw);
                 ) {
                String line = null;
                // 包含行内容的字符串，不包括
                // 任何行终止符，如果末尾为null

                while ((line=bf.readLine())!=null){
                    bfw.write(line);
                    // 写完当前行后就换行 使用的是系统的换行符 在window下是
                    //bfw.write("\r\n ");
                    // 在liux下 是 \n
                    bfw.newLine();
                }
         }catch (Exception e){
             System.out.println("拷贝失败");
             e.printStackTrace();
         }





    }

    /**
     * 使用字节缓冲流，拷贝图片
     * * 步骤：1 定义try catch resources
     * *      2 创建FileInputStream和FileOutputStream对象
     * *      3 创建BufferedOutputStream和BufferedInputStream对象
     * *      4 将FileInputStream和FileOutputStream注入到BufferedInputStream和BufferedOutputStream
     * *      5 定义byte数组存储每次读取的数据
     * *      6 定义整数变量存储每次读取的有效字节数量
     * *      7 没有到达文件末尾的情况下一致读取数据
     * *      8 将读取的数据写入目的磁盘
     */
    private static void method03() {
        long start = System.currentTimeMillis();
        try (
                InputStream in = new FileInputStream("1609316536101.jpg");
                OutputStream out = new FileOutputStream("day_23/拷贝图片.jpg");
        ) {
            byte[] data = new byte[1024];
            int len = 0;
            while ((len = in.read(data)) != -1) {
                out.write(data, 0, len);
            }
            long end = System.currentTimeMillis();
            System.out.println("耗时:" + (end - start));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 描述:
     * 使用字符流完成文本文件的拷贝
     * 使用文件字符流做辅助来帮助 拷贝文本文件
     */
    private static void method02() {
        try {
            cpoy("day_23/b.txt", "day_23/拷贝b.txt");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 场景：使用字符流完成文本文件的拷贝
     * * 要求：文件拷贝是一个独立的行为，我们可以定义一个静态方法copy(String srcPath,String destPath)完成拷贝粘贴功能，最后由main方法
     * * 调用copy方法
     * * 步骤：1 定义静态方法copy(String srcPath,String destPath)
     * *         参数1：磁盘文件源路径， 参数2：磁盘文件目的路径
     * *      2 在copy方法中定义 try with resources
     * *      3 创建基于字符的文件输入和输出管道
     * *      4 定义字符数组，存储读取的数据
     * *      5 定义整数变量存储读取的有效字符长度
     * *      6 调用FileReader的read(char[])方法读取数据，将读取的结果存储到字符数组中
     * *      7 判断读取的有效字符长度是否为-1，如果等于-1表示读取到末尾，终止循环
     * *      8 如果不等于-1表示有数据，将读取的数据使用FileWriter的write(char[],int,int)方法写入目的磁盘路径
     * 复制文件工具类
     *
     * @param src  原路径文本文件
     * @param desk 目标路径和文本文件名
     * @throws Exception
     */
    public static void cpoy(String src, String desk) throws Exception {
        //
        FileReader fr = new FileReader(src);
        FileWriter fw = new FileWriter(desk);

        // 字符流拷贝文本文件是字节流的两倍速度 英文一个字符 占 两个字节
        char[] data = new char[1024];
        int len = 0;
        while ((len = fr.read(data)) != -1) {
            System.out.println("111");
            fw.write(data, 0, len);
            // 还是要fw.flush();
            // 这里没有使用 try -with -resources 所以没有自动关闭资源
            fw.flush();
        }
    }

    /**
     *  场景：使用缓冲输入流读取磁盘数据并且打印
     * 步骤：1 定义try with resources
     *      2 创建FileInputStream对象，指定磁盘文件的路径
     *      3 创建BufferedInputStream对象，将FileInputStream注入到它里面
     *      4 定义byte数组存储读取的数据
     *      5 定义整形变量存储读取的有效字节数
     *      6 定义StringBuilder存储读取的所有数据
     *      7 使用BufferedInputStream的read(byte[])方法读取数据，读取到-1结束
     *      8 将读取的数据转换为String
     *      9 将String追加到StringBuilder中
     *      10 打印StringBuilder读取的结果
     */
    /**
     * 功能描述: <br>
     * 字符缓冲流的读文件并打印到控制台
     *
     * @return:
     * @date: 2020/12/30 20:13
     */
    private static void method01() {
        try (InputStream os = new FileInputStream("day_23/b.txt")) {
            BufferedInputStream bis = new BufferedInputStream(os);
            byte[] bytes = new byte[1024];
            int len = 0;
            StringBuilder builder = new StringBuilder();
            while ((len = bis.read(bytes)) != -1) {
                // 解码字节数组-> str
                String str = new String(bytes, 0, len);
                builder.append(str);
            }
            System.out.println(builder);
            System.out.println("读取成功");
        } catch (Exception e) {
            System.out.println("读取失败");
            e.printStackTrace();
        }
    }
}
